package com.api.controller

import com.api.IFinal
import com.api.async.Async_API
import com.api.rpc.RPC_Service1_Feign
import com.api.rpc.RPC_Socket
import com.base.model.api.Model_API
import com.base.model.service1.Model_Service1
import com.base.model.service1.db.Model_Service1_MyBatisDB
import com.base.model.service1.db.Model_Service1_MyBatisPlusDB
import com.base.model.service1.db.Model_Service1_Redis
import com.base.service.IRPC_API
import com.base.service.IRPC_Service1_Dubbo
import com.yfree.global.YController
import com.yfree.mq.YMQService
import io.seata.spring.annotation.GlobalTransactional
import org.apache.dubbo.config.annotation.DubboReference
import org.springframework.beans.factory.annotation.Value
import org.springframework.cloud.context.config.annotation.RefreshScope
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.request.ServletRequestAttributes

@RefreshScope
@RestController
class Controller_API(
    @Value("\${yangzhe.config1}") var config1: String,
    @Value("\${yangzhe.config2}") var config2: String,
    @Value("\${nacos-key:default-value}") var nacosKey: String,
    var ymqService: YMQService,
    var async_API: Async_API,
    var rpc_Service1_Feign: RPC_Service1_Feign,
    var rpc_Socket: RPC_Socket
) : YController(), IRPC_API {
    @DubboReference(group = "service1", version = "1", check = false)
    lateinit var rpc_Service1_Dubbo: IRPC_Service1_Dubbo

    @GlobalTransactional
    override fun index() = yResult()

    @GlobalTransactional
    override fun `interface`(jkid: String, jkparam: Any?): String {
        val servletRequestAttributes = RequestContextHolder.getRequestAttributes() as ServletRequestAttributes
        val request = servletRequestAttributes.request
        val response = servletRequestAttributes.response
        val params = yParams(jkparam, Map::class.java)
        return when (jkid) {
            "00A00" -> { // 模拟出参
                val apiModel = Model_API()
                apiModel.key = "value"
                yResult(result = listOf(apiModel))
            }

            "00A01" -> { // 发送socket
                val param_socketID = params["socketID"].toString()
                val param_message = params["message"].toString()
                yFromRPC(rpc_Socket.send(param_socketID, param_message), "rpc_Socket.send调用失败")
                yResult()
            }

            "00A02" -> { // MySQL_Mybatis
                val param_id = params["id"]?.toString() ?: "1"
                val yModel = yFromRPC(rpc_Service1_Feign.db_MySQL(param_id), Model_Service1_MyBatisDB::class.java, "rpc_Service1_Feign.db_MySQL调用失败")
                yResult(result = yModel.root.result)
            }

            "00A03" -> { // MySQL_MybatisPlus
                val param_id = params["id"]?.toString() ?: "1"
                val yModel = yFromRPC(rpc_Service1_Feign.db_MySQL_MP(param_id), Model_Service1_MyBatisPlusDB::class.java, "rpc_Service1_Feign.db_MySQL_MP调用失败")
                yResult(result = yModel.root.result)
            }

            "00A04" -> { // MongoDB
                val param_id = params["id"].toString()
                val yModel = yFromRPC(rpc_Service1_Feign.db_MongoDB(param_id), Model_Service1_MyBatisDB::class.java, "rpc_Service1_Feign.db_MongoDB调用失败")
                yResult(result = yModel.root.result)
            }

            "00A05" -> { // Redis
                val param_id = params["id"].toString()
                val yModel = yFromRPC(rpc_Service1_Feign.db_Redis(param_id), Model_Service1_Redis::class.java, "rpc_Service1_Feign.db_Redis调用失败")
                yResult(result = yModel.root.result)
            }

            "00A06" -> { // 获取自定义配置
                val apiModel = Model_API()
                apiModel.config1 = config1
                apiModel.config2 = config2
                apiModel.nacosKey = nacosKey
                yResult(result = listOf(apiModel))
            }

            "00A07" -> { // RPC-Feign
                val yModel = yFromRPC(rpc_Service1_Feign.callService2(), Model_Service1::class.java, "rpc_Service1_Feign.callService2调用失败")
                yResult(result = yModel.root.result)
            }

            "00A08" -> { // Feign+Seata
                yFromRPC(rpc_Service1_Feign.do_feign("0"), "rpc_Service1_Feign.do_seata调用失败") //当code != YConfig.Response.successCode，会默认启动回滚
                yResult()
            }

            "00A09" -> { // Feign+Seata+Exception
                yFromRPC(rpc_Service1_Feign.do_feign("1"), "rpc_Service1_Feign.do_seata调用失败") //当code != YConfig.Response.successCode，会默认启动回滚
                yResult()
            }

            "00A10" -> { // RPC-Dubbo
                val yModel = yFromRPC(rpc_Service1_Dubbo.callService2(), Model_Service1::class.java, "rpc_Service1_Dubbo.callService2调用失败")
                yResult(result = yModel.root.result)
            }

            "00A11" -> { // Dubbo+Seata
                yFromRPC(rpc_Service1_Dubbo.do_seata("0"), "rpc_Service1_Dubbo.do_seata调用失败") //当code != YConfig.Response.successCode，会默认启动回滚
                yResult()
            }

            "00A12" -> { // Dubbo+Seata+Exception
                yFromRPC(rpc_Service1_Dubbo.do_seata("1"), "rpc_Service1_Dubbo.do_seata调用失败") //当code != YConfig.Response.successCode，会默认启动回滚
                yResult()
            }

            "00A13" -> { // 异步执行
                async_API.async()
                yResult(message = "任务同步完成")
            }

            "00A14" -> { // 客户端请求头
                val sign = request.getAttribute(IFinal.signKey) as Map<*, *>
                val apiModel = Model_API()
                apiModel.channel = sign["channel"].toString()
                apiModel.device = sign["device"].toString()
                apiModel.version = sign["version"].toString()
                apiModel.uid = sign["uid"].toString()
                yResult(result = listOf(apiModel))
            }

            "00A15" -> { // RocketMQ
                if (ymqService.send(mapOf("message" to "消息内容")))
                    yResult()
                else yResult(code = -1, message = "MQ消息发送失败")
            }

            "00A16" -> { // Redis Lock
                yResult(message = yRunLock("${javaClass.enclosingMethod.name}_$jkid") {
                    return@yRunLock "加锁运行的结果"
                })
            }

            else -> yResult(code = 404, message = "jkid不存在")
        }
    }
}